﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using Fetches.Fetch.Dto;

namespace FetchesDeploy.Distributed.Factory.Mapping
{
    public class FetcherPool
    {
        /// <summary>
        ///     所有未完成爬取的Fetcher,其实我需要的是线程安全的hashset
        /// </summary>
        private readonly ConcurrentDictionary<long, long> _unfinishedFetchers =
            new ConcurrentDictionary<long, long>();

        /// <summary>
        ///     待分配Fetcher
        /// </summary>
        private readonly ConcurrentDictionary<string, ISet<long>> _restFetchers =
            new ConcurrentDictionary<string, ISet<long>>();

        /// <summary>
        ///     任务入列
        /// </summary>
        /// <param name="task"></param>
        public void RegisterUnfinishedFetchTask(FetchTask task)
        {
            foreach (var fetcherId in task.FetcherIds)
            {
                _unfinishedFetchers.TryAdd(fetcherId, fetcherId);
            }

        }

        /// <summary>
        /// 移除任务
        /// </summary>
        /// <param name="task"></param>
        public void UnRegisterFetchTask(FetchTask task)
        {
            foreach (var fetcherId in task.FetcherIds)
            {
                if (_unfinishedFetchers.TryRemove(fetcherId, out _))
                {
                    RemoveFetcherFromRestZone(fetcherId, task.FetchOrder.FetcherTypeName);
                }
            }

        }

        //将Fetcher添加到待分配区域
        public void PutFetchersIntoRestZone(IEnumerable<long> fetcherIds, string fetcherType)
        {
            foreach (var fetcherId in fetcherIds)
            {
                PutFetcherIntoRestZone(fetcherId, fetcherType);
            }
        }

        //将任务分片添加到待分配区域
        public void PutFetcherIntoRestZone(long fetcherId, string fetcherType)
        {
            lock (_restFetchers)
            {
                if (!_restFetchers.TryGetValue(fetcherType, out ISet<long> fetcherIds))
                {
                    fetcherIds = new HashSet<long>();
                    _restFetchers.TryAdd(fetcherType, fetcherIds);
                }

                fetcherIds.Add(fetcherId);
            }

        }

        //将任务分片移出待分配区
        public void RemoveFetcherFromRestZone(long fetcherId, string fetcherType)
        {
            lock (_restFetchers)
            {
                if (_restFetchers.TryGetValue(fetcherType, out ISet<long> fetchers))
                {
                    try
                    {
                        fetchers.Remove(fetcherId);
                    }
                    catch (Exception)
                    {
                        //
                    }

                }
            }

        }

        public IDictionary<string, ISet<long>> GetGroupedRestingFetchTask()
        {
            return _restFetchers;
        }
    }
}
